#ifndef BIG_INT_H_
#define BIG_INT_H_

#include <iostream>


class BigInt
{
public:

	static const int BASE = 10000;
	static const int BASE_LOG10 = 4;
	static const int MAX_LENGTH = 255; // max length in BigInt digits

	typedef short int DigitType;
	
	DigitType coeff[MAX_LENGTH];
	int length;

public:

	typedef short ShortType; // what is considered as "short" type

	BigInt();
	BigInt(const char* str10);
	BigInt(long long int a);

	BigInt operator + (const BigInt& b) const;
	BigInt operator - (const BigInt& b) const;
	BigInt operator * (const ShortType b) const;
	BigInt operator * (const BigInt& b) const;
	BigInt operator / (const BigInt& b) const;
	BigInt operator / (ShortType b) const;
	bool operator < (const BigInt& b) const;
	bool operator > (const BigInt& b) const;
	bool operator <= (const BigInt& b) const;
	bool operator >= (const BigInt& b) const;
	bool operator == (const BigInt& b) const;
	bool operator != (const BigInt& b) const;

	void Div(ShortType b, BigInt& quotient, ShortType& remainder);
	void Div(const BigInt& b, BigInt& quotient, BigInt& remainder);

	friend std::ostream& operator << (std::ostream& os, const BigInt& b);
	friend std::istream& operator >> (std::istream& os, BigInt& b);

protected:
	DigitType& operator[](int i) { return this->coeff[i]; }
	DigitType operator[](int i) const { return this->coeff[i]; }
	void fromString(const char* str10);
};

std::ostream& operator << (std::ostream& os, const BigInt& b);
std::istream& operator >> (std::istream& os, BigInt& b);

#endif